<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
require_once "net/zemberek/bilgi/KaynakYukleyici.php";
require_once "net/zemberek/istatistik/Istatistikler.php";
require_once "java/lang/Character.php";
/**
 * Verilen bir dosyadan veya herhangi bir stream'den Türkçe kelimeleri sırasıyla almak için kullanılır.
 * 
 *
 * @author Sedat Sevgili
 * 
 * @todo: Test için net/zemberek/istatistik/Istatistikler.php'nin hazırlanması gerekmektedir.
 */
class TurkishTokenStream {
    //put your code here
    
    public $bis = null;
    public $statistics = null;
    public $buffer = array();
    public $index = 0;
    
    public static $MAX_KELIME_BOY = 256;
    private $kelimeBuffer = array();
    
    public static $MAX_CUMLE_BOY = 4000;
    private $cumleBuffer = array();
    
    function __construct() {
        $args = func_get_args();
        if(count($args) != 2) {
            throw new Exception("Geçersiz argüman listesi");
        }
        /**
         * $args[0] ya dosya ismi ya da dosyayı açmış bir file handler olmalıdır.
         * $args[1] encoding ismi olmalıdır.
         */
        $kaynakYukleyici = new KaynakYukleyici($args[1]);
        $this->bis = $kaynakYukleyici->getReader($args[0]);
    }
    
    public function nextWord() {
        $ch = '';
        $readChar = 0;
        $kelimeBasladi = false;
        $kelimeIndex = 0;
        $hypen = false;
        while(($readChar = fread($this->bis, 1)) !== false) {
            $ch = $readChar;
            if(!is_null($this->statistics)) {
                $this->statistics->processChar($ch);
            }
            if($ch == '-') {
                $hypen = true;
                continue;
            }
            if(Character::isLetter($ch) || ($kelimeBasladi == true && ($ch == '\'' || $ch == '-'))) {
                $kelimeBasladi = true;
                $hypen = false;
                if($kelimeIndex < self::$MAX_KELIME_BOY) {
                    $this->kelimeBuffer[$kelimeIndex++] = $ch;
                } else {
                    echo "maksimum kelime boyu aşıldı. " . $ch . PHP_EOL;
                }
                continue;
            }
            
            if(Character::isWhitespace($ch)) {
                if($hypen) {
                    continue;
                }
                if($kelimeBasladi) {
                    return implode('', $this->kelimeBuffer);
                }
                $kelimeBasladi = false;
                $kelimeIndex = 0;
                continue;
            }
        }
        
        // Tüm karakterler bitti, son kalan kelime varsa onu da getir.
        if($kelimeBasladi) {
            return implode('', $this->kelimeBuffer);
        }
        return null;
    }
    
    public function nextSentence() {
        $ch = '';
        $readChar = 0;
        $cumleBasladi = false;
        $cumleIndex = 0;
        while(($readChar = fread($this->bis, 1)) !== false) {
            $ch = $readChar;
            if(Character::isLetter($ch) || $ch == '\'' || $ch == '-') {
                $cumleBasladi = true;
                if($cumleIndex < self::$MAX_CUMLE_BOY) {
                    $this->cumleBuffer[$cumleIndex++] = $ch;
                } else {
                    echo "Lagim tasti " . $ch;
                }
                continue;
            }
            
            if($this->isSentenceDelimiter($ch)) {
                if($cumleBasladi) {
                    return implode('', $this->cumleBuffer);
                }
                continue;
            }
            
            if($cumleIndex < self::$MAX_CUMLE_BOY) {
                $this->cumleBuffer[$cumleIndex++] = $ch;
            } else {
                echo "Lagim tasti " . $ch;
                return null;
            }
        }
        
        if($cumleBasladi) {
            return implode('', $this->cumleBuffer);
        }
        return null;
    }
    
    public function harfIsle($chIn) {
        $ch = '';
        switch($chIn) {
            case 'I':
                $ch = '\u0131';
                break;
            // buraya şapkalı a vs gibi karakter dönüşümleri de eklenebilir.
            default:
                $ch = Character::toLowerCase($chIn);
        }
        return $ch;
    }
    
    public function isSentenceDelimiter($ch) {
        if($ch == '.' || $ch == ':' || $ch == '!' || $ch == '?') {
            return true;
        }
        return false;
    }
    
    public function setStatistics($statistics) {
        $this->statistics = $statistics;
    }
}